﻿using SearchInFiles.Lib.Data;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using UtilityToolsCollect.UtilityToolsCollect.SerializeToolUtility;

namespace SearchInFiles.Global
{
    [Serializable]public class Config : INotifyPropertyChanged
    {
        private static readonly string SettingFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Setting.config");
        private static Config? m_Instance;
        public static Config Instance => m_Instance ??= Load();
        private static Config Load()
        {
            if (!File.Exists(SettingFilePath))
            {
                m_Instance = new();
                Save();
                return m_Instance;
            }
            try { return XmlSerialize.FileAndPathTool.PathToXmlDeserialize<Config>(SettingFilePath); }
            catch { return new(); }
        }
        public static void Save() => XmlSerialize.FileAndPathTool.XmlSerializerToXmlFile(SettingFilePath, m_Instance, true);

        public event PropertyChangedEventHandler? PropertyChanged;

        private ObservableCollection<string>? m_SearchHistory;
        [XmlArray]public ObservableCollection<string> SearchHistory
        {
            get => m_SearchHistory ??= new ObservableCollection<string>();
            set { if (m_SearchHistory == value) return; m_SearchHistory = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SearchHistory))); }
        }

        private ObservableCollection<SearchFileType>? m_TextFileTypes;
        [XmlArray]public ObservableCollection<SearchFileType> TextFileTypes
        {
            get => m_TextFileTypes ??= new ObservableCollection<SearchFileType>();
            set { if (m_TextFileTypes == value) return; m_TextFileTypes = value; 
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TextFileTypes))); 
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllFileTypes))); }
        }
        private ObservableCollection<SearchFileType>? m_ExtensionFileTypes;
        [XmlArray]public ObservableCollection<SearchFileType> ExtensionFileTypes
        {
            get => m_ExtensionFileTypes ??= new ObservableCollection<SearchFileType>();
            set { if (m_ExtensionFileTypes == value) return; m_ExtensionFileTypes = value; 
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ExtensionFileTypes))); 
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllFileTypes))); }
        }
        [XmlIgnore] public SearchFileType[] AllFileTypes => TextFileTypes.Concat(ExtensionFileTypes).ToArray();
        [XmlIgnore] public IEnumerable<SearchFileType> ValidExtensionFiles => TextFileTypes.Concat(ExtensionFileTypes).Where(p => p.Enable);

        [XmlIgnore] public HashSet<string> ValidExtensionAllSet => new HashSet<string>(ValidExtensionFiles.Select(p => p.TypeExtension));
        [XmlIgnore] public HashSet<string> ValidTextExtensionSet => new HashSet<string>(TextFileTypes.Where(p => p.Enable).Select(p => p.TypeExtension));
        [XmlIgnore] public HashSet<string> TextFileTypesSet => new HashSet<string>(TextFileTypes.Select(p => p.TypeExtension));
        [XmlIgnore] public HashSet<string> ExtensionFileTypesSet => new HashSet<string>(ExtensionFileTypes.Select(p => p.TypeExtension));

        public void AllFileTypesUpdate()=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllFileTypes)));


    }
}
